# 传递任意数量的实参
# 有时候，预先不知道函数需要接受多少个实参，好在Python允许函数从调用语句中收集任意数量的实参。
# 来看一个制作比萨的函数，它需要接受很多配料，但无法预先确定顾客要多少种配料。
# 下面的函数只有一个形参*toppings ，但不管调用语句提供了多少实参，这个形参会将它们统统收入囊中：
# pizza.py
def make_pizza(*toppings):
	"""打印顾客点的所有配料"""
	print(toppings)

make_pizza('pepperoni')
make_pizza("mushrooms", 'green peppers', 'extra cheese')
# 形参名 *toppings 中的星号让Python创建一个名为toppings 的空元组，并将收到的所有值都封装到这个元组中。
# 函数体内的函数调用print() 通过生成输出，证明Python能够处理使用一个值来调用函数的情形，也能处理使用三个值来调用函数的情形。
# 它以类似的方式处理不同的调用。
# 注意，Python将实参封装到一个元组中，即便函数只收到一个值

# 可以将函数调用print() 替换为一个循环，遍历配料列表并对顾客点的比萨进行描述:
def make_pizza_new(*toppings):
	"""概述要制作的披萨"""
	print("\nMaking a pizza with the following toppings:")
	for topping in toppings:
		print(f"- {topping}")

make_pizza_new('pepperoni')
make_pizza_new("mushrooms", 'green peppers', 'extra cheese')

# 不管函数收到的实参是多少个，这种语法都管用。


# 结合使用位置实参和任意数量实参
# 如果要让函数接受不同类型的实参，必须在函数定义中将接纳任意数量实参的形参放在最后。
# Python先匹配位置实参和关键字实参，再将余下的实参都收集到最后一个形参中。
# 例如，如果前面的函数还需要一个表示比萨尺寸的形参，必须将其放在形参*toppings 的前面：
def make_pizza_plus(size, *toppings):
	"""概述要制作的披萨"""
	print(f"\nMaking a {size}-inch pizza with the following toppings:")
	for topping in toppings:
		print(f"- {topping}")

make_pizza_plus(16, 'pepperoni')
make_pizza_plus(12, "mushrooms", 'green peppers', 'extra cheese')

# 注意 　你经常会看到通用形参名 *args ，它也收集任意数量的位置实参。


# 使用任意数量的关键字实参
# 有时候，需要接受任意数量的实参，但预先不知道传递给函数的会是什么样的信息。
# 在这种情况下，可将函数编写成能够接受任意数量的键值对——调用语句提供了多少就接受多少。
# 一个这样的示例是创建用户简介：你知道将收到有关用户的信息，但不确定会是什么样的信息。
# 在下面的示例中，函数build_profile() 接受名和姓，还接受任意数量的关键字实参：
# user_profile.py
def build_profile(first, last, **user_info):
	"""创建一个字典，其中包含我们知道的有关用户的一切"""
	user_info['first_name'] = first
	user_info['last_name'] = last
	return user_info

user_profile = build_profile('albert', 'einstein', location='princeton', field='physics')
print(user_profile)
# 函数build_profile() 的定义要求提供名和姓，同时允许根据需要提供任意数量的名称值对。
# 形参**user_info 中的两个星号让Python创建一个名为user_info 的空字典，并将收到的所有名称值对都放到这个字典中。
# 在这个函数中，可以像访问其他字典那样访问user_info 中的名称值对。
# 在build_profile() 的函数体内，将名和姓加入了字典user_info 中,因为总是会从用户那里收到这两项信息，
# 而这两项信息没有放到这个字典中。接下来，将字典user_info 返回到函数调用行。
# 我们调用build_profile() ，向它传递名（'albert' ）、姓（'einstein' ）和两个键值对（location='princeton' 和
# field='physics' ），并将返回的user_info 赋给变量user_profile ，再打印该变量
# 该函数返回的字典包含用户的名和姓，还有求学的地方和所学专业。
# 调用这个函数时，不管额外提供多少个键值对，它都能正确地处理。

# 注意 　你经常会看到形参名**kwargs ，它用于收集任意数量的关键字实参。
